home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
80x0393.zip
/
UART_TUT.FAQ
< prev
next >
Wrap
Text File
|
1993-03-30
|
27KB
|
593 lines
The Serial Hardware Tutorial
By Yousuf J. Khan (FidoNet 1:163/215.4)
Revision: Jan 20, 1993
Serial communications on the IBM PC and compatible range of computers
conforms to the RS-232C serial port standard. The chip that implements
and controls the RS-232 serial port is the UART.
BIOS Data Segment
-----------------
The base port addresses of each UART can be pointed to by reading the
four memory words at offset 0, 2, 4, and 6 from the start of the BIOS
Data Segment (BDS), segment 40h. Each word points to the starting port
address of a UART assembly. These pointer words are known commonly as
COM1, COM2, COM3, and COM4.
Some standard base port locations to put the UART assemblies are at
ports 02E8h, 02F8h, 03E8h, and 03F8h, in no particular order. If one of
the port pointers is zero, then that indicates that a serial port does
not exist there.
Any code snippets in this tutorial are compatible with Tasm 2.0
assembler (but likely will work with many other versions of assemblers).
They may refer to a fictional memory location known as [COMX]. [COMX] is
a word variable representing anything from COM1 through COM4.
The UART
--------
There have been about four major functional revisions of the UART. The
first one in the series was the National Semiconductor 8250.
The next version was the NS 16450. There was also an 8250A, which was
functionally identical to the 16450, therefore is really just a 16450.
The addition of a scratch register is what distinguishes a 16450 from
the 8250.
After the 16450, came the 16550A. The 16550A added a 16 byte FIFO buffer
to the data register. The FIFOs insulate the serial communications from
disruptions caused by high interrupt latencies in the computer. There
was also a 16550 (non-A), but that one had disfunctional FIFOs, so it
looks and acts just like a 16450. From now on any references to a
"16550" assumes we are talking about the 16550A revision and later.
The most recent addition to the family are the Type 3 UARTs, found in
late model IBM PS/2's. The Type 3's can read and write data using the
DMA circuitry of the PC. There is also a new, switchable, higher speed
baud rate clock on the Type 3's, which raise maximum baud rates by 6
fold.
The Data register (offset 0)
----------------------------
The data register is at offset zero in the port addresses. If you read
from it, it becomes the Receive Data register, and if you write to it,
it becomes the Transmit Data register. The data register is eight bits
long, and is common to all revisions.
If you have an UART with FIFOs (ie. 16550+ only), and they are enabled,
then you do not have to stop reading or writing after doing just one.
You may simply keep reading until the receiver FIFO is empty. Or you may
simply keep writing until the transmitter FIFO is full. Each character
will get pushed up through the FIFO stack.
The Interrupt Enable register (offset 1)
----------------------------------------
At the port offset one is the Interrupt Enable register. This register
controls what sorts of change of state will cause the UART to interrupt
the CPU. You write to this port to set the states, and you read from
this port to get the states. Only the first four bits (bits 0-3) are
defined, the remainder are zero.
7 4 3 2 1 0
┌──────┬────┬────┬───┬───┐
│ 0000 │ MS │ LS │ T │ R │
└──────┴────┴────┴───┴───┘
Bit 0 (R): enable Receive data ready int
Bit 1 (T): enable Transmit data empty int
Bit 2 (LS): Line Status int. Any change in the Line Status
register with this bit set will cause an int.
Bit 3 (MS): Modem Status int. Any change in the Modem Status
register with this bit set will cause an int.
Bits 4-7: reserved, cleared.
Sample code:
;The following is an example of setting only the MS bit without
;turning on any of the other bits.
...
IER record ms:1,ls:1,t:1,r:1
mov dx, [comx] ;get comport address
inc dx ;one offset from base
mov al, IER <1,0,0,0> ;set just MS bit
out dx, al
...
The Interrupt ID register (offset 2)
------------------------------------
The register at this offset has a split personality depending on whether
you are reading from or writing to it. If you are reading from it, then
this is the Interrupt ID reg. For the 8250 & 16450, this register has
only the bit fields 0-2 defined. For the 16550 and above, three
additional bit fields have been defined. All undefined fields, on any
particular revision, are cleared.
7 6 5 4 3 2 1 0
┌──────┬────┬────┬────┬───┐
│ FIFO │ 00 │ FT │ ID │ I │
└──────┴────┴────┴────┴───┘
Bit 0 (I): Interrupt pending. Simply indicates an interrupt
occurred, but not what the cause was (as set by
Interrupt Enable register).
Bits 1-2 (ID): Indicates what the cause of the interrupt was.
00b Look in Modem Status register
01b Transmit data int occurred
10b Receive data int occurred
Bit 3 (FT): 16550+ only. FIFO Timeout. Set only in conjunction
with ID bits = 10b (Receive data) condition. Allows the
processor to read the last few bytes left in the FIFO
buffer, which would otherwise be not enough to trigger a
full receive data int.
Bits 4-5: reserved, cleared
Bits 6-7 (FIFO): 16550+ only. Mode status.
00b Char mode, ie. emulate 8250 or 16450.
01b DMA mode. Type 3 UART only.
11b FIFO mode.
Sample code:
;The following is a sample interrupt handler which determines
;if an int occurred & what sort of int occurred.
...
IID record fifo:2,rsrv:2=0,ft:1,id:2,i:1
mov dx, [comx]
add dx, 2 ;two offsets from base
in al, dx
test al, mask i ;did an int occur on this comport?
jne no_irq ;no? then branch
and al, mask id ;mask all but ID bits
cmp al, iid <,,,01b,>;transmit data empty int?
pop ax ;restore AL
je transdata ;yes? then write to buffer
cmp al, iid <,,,10b,>;received data int?
je rcvdata ;yes? then read buffer
...
rcvdata:
...
transdat:
...
no_irq:
...
The FIFO Control register (offset 2)
------------------------------------
This is the other half of the Interrupt ID register, but only available
in write mode, and only available on the 16550+ UART. It is used to
control various aspects of the FIFO buffers.
7 6 5 3 2 1 0
┌─────┬─────┬────┬────┬────┐
│ FTS │ 000 │ TR │ RR │ FE │
└─────┴─────┴────┴────┴────┘
Bit 0 (FE): FIFO Enable
Bit 1 (RR): Receive buffer reset
Bit 2 (TR): Transmit buffer reset
Bits 3-5: reserved, cleared
Bit 6-7 (FTS): FIFO Trigger Size. Sets how full the receive
FIFOs may get before it ints.
00b 1 byte
01b 4 bytes
10b 8 bytes
11b 14 bytes
The Line Control register (offset 3)
------------------------------------
Common to all revisions. You use this register to set things like baud
rates, word size, parity, etc.
7 6 5 4 3 2 1 0
┌───┬───┬────┬────┬───┬───┬────┐
│ D │ B │ SP │ EP │ P │ S │ WS │
└───┴───┴────┴────┴───┴───┴────┘
Bits 0-1 (WS): Word Size. Number of data bits.
00b 5 bits
01b 6 bits
10b 7 bits
11b 8 bits
Bit 2 (S): Number of Stop bits (one or